package com.yaowk.sfp.utils.generator;

import lombok.Data;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.persistence.Entity;
import java.io.File;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

/**
 * 代码生成器
 */
@Data
public class Generator {

    private DaoGenerator daoGenerator; // dao生成器
    private ModelGenerator modelGenerator; // model生成器
    private ServiceGenerator serviceGenerator; // service接口生成器
    private ServiceImplGenerator serviceImplGenerator; // service实现类生成器
    private ServiceBaseGenerator serviceBaseGenerator; // service基类生成器
    private ModelBaseGenerator modelBaseGenerator; // model基类生成器
    private String entityPackage; // 实体的包名
    private String basePath; // 基本路径
    private Class[] include; // 包含实体 若包含实体与排除实体同时存在，优先包含实体
    private Class[] exclude; // 排除实体

    private boolean enabledDao;
    private boolean enabledModel;
    private boolean enabledModelBase;
    private boolean enabledService;
    private boolean enabledServiceImpl;
    private boolean enabledServiceBase;

    /**
     * @param entityPackage 实体的包名
     */
    public Generator(String entityPackage) {
        this(entityPackage, "/src/main/java/");
    }

    /**
     * @param entityPackage 实体的包名
     * @param basePath      实体的项目路径
     */
    public Generator(String entityPackage, String basePath) {
        daoGenerator = new DaoGenerator();
        modelGenerator = new ModelGenerator();
        serviceImplGenerator = new ServiceImplGenerator();
        serviceGenerator = new ServiceGenerator();
        serviceBaseGenerator = new ServiceBaseGenerator();
        modelBaseGenerator = new ModelBaseGenerator();
        this.basePath = basePath;
        this.entityPackage = entityPackage;
    }

    public void setEntityPrefix(String prefix) {
        daoGenerator.setEntityPrefix(prefix);
        modelGenerator.setEntityPrefix(prefix);
        serviceGenerator.setEntityPrefix(prefix);
        serviceImplGenerator.setEntityPrefix(prefix);
        serviceBaseGenerator.setEntityPrefix(prefix);
        modelBaseGenerator.setEntityPrefix(prefix);
    }

    public void setEntitySuffix(String suffix) {
        daoGenerator.setEntitySuffix(suffix);
        modelGenerator.setEntitySuffix(suffix);
        serviceGenerator.setEntitySuffix(suffix);
        serviceImplGenerator.setEntitySuffix(suffix);
        serviceBaseGenerator.setEntitySuffix(suffix);
        modelBaseGenerator.setEntitySuffix(suffix);
    }


    public void setDaoInit(String packageName, String basePath) {
        if (StringUtils.isEmpty(basePath)) {
            basePath = this.basePath;
        }
        enabledDao = true;
        daoGenerator.setPackageName(packageName);
        daoGenerator.setBasePath(basePath);
    }

    public void setModelInit(String packageName, String basePath) {
        if (StringUtils.isEmpty(basePath)) {
            basePath = this.basePath;
        }
        enabledModel = true;
        modelGenerator.setPackageName(packageName);
        modelGenerator.setBasePath(basePath);
        if (StringUtils.isEmpty(modelBaseGenerator.getPackageName())) {
            enabledModelBase = true;
            modelBaseGenerator.setPackageName(packageName + ".base");
            modelBaseGenerator.setBasePath(basePath);
        }
    }

    public void setModelBaseInit(String packageName, String basePath) {
        if (StringUtils.isEmpty(basePath)) {
            basePath = this.basePath;
        }
        enabledModelBase = true;
        modelBaseGenerator.setPackageName(packageName);
        modelBaseGenerator.setBasePath(basePath);
    }

    public void setServiceInit(String packageName, String basePath) {
        if (StringUtils.isEmpty(basePath)) {
            basePath = this.basePath;
        }
        enabledService = true;
        serviceGenerator.setPackageName(packageName);
        serviceGenerator.setBasePath(basePath);
    }

    public void setServiceImplInit(String packageName, String basePath) {
        if (StringUtils.isEmpty(basePath)) {
            basePath = this.basePath;
        }
        enabledServiceImpl = true;
        serviceImplGenerator.setPackageName(packageName);
        serviceImplGenerator.setBasePath(basePath);
        if (StringUtils.isEmpty(serviceBaseGenerator.getPackageName())) {
            enabledServiceBase = true;
            serviceBaseGenerator.setPackageName(packageName + ".base");
            serviceBaseGenerator.setBasePath(basePath);
        }
    }

    public void setServiceBaseInit(String packageName, String basePath) {
        if (StringUtils.isEmpty(basePath)) {
            basePath = this.basePath;
        }
        enabledServiceBase = true;
        serviceBaseGenerator.setPackageName(packageName);
        serviceBaseGenerator.setBasePath(basePath);
    }

    public void generator() throws Exception {

        // 整理实体
        List<Class> entities = new ArrayList<>();

        if (ObjectUtils.isEmpty(include)) {
            // 未指定包含实体，获取所有实体
            File dir = new File(GeneratorUtils.getPath(entityPackage, basePath));
            if (!dir.isDirectory()) {
                return;
            }
            File[] files = dir.listFiles();
            for (File file : files) {
                try {
                    String fileName = file.getName();
                    fileName = fileName.substring(0, fileName.lastIndexOf("."));
                    Class clazz = Class.forName(entityPackage + "." + fileName);
                    // 需要Entity注解
                    Annotation annotation = clazz.getAnnotation(Entity.class);
                    if (!ObjectUtils.isEmpty(annotation)) {
                        entities.add(clazz);
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    throw new RuntimeException("entity加载错误");
                }
            }
            System.out.println(entities);

            // 排除实体
            if (!ObjectUtils.isEmpty(exclude)) {
                for (Class clazz : exclude) {
                    entities.remove(clazz);
                }
            }
        } else {
            // 使用指定实体
            for (Class clazz : include) {
                entities.add(clazz);
            }
        }

        // 注入entity
        daoGenerator.setEntities(entities);
        modelGenerator.setEntities(entities);
        serviceGenerator.setEntities(entities);
        serviceImplGenerator.setEntities(entities);
        serviceBaseGenerator.setEntities(entities);
        modelBaseGenerator.setEntities(entities);

        // 注入参数
        modelGenerator.setModelBaseGenerator(modelBaseGenerator);

        serviceGenerator.setModelGenerator(modelGenerator);

        serviceImplGenerator.setServiceGenerator(serviceGenerator);
        serviceImplGenerator.setServiceBaseGenerator(serviceBaseGenerator);

        serviceBaseGenerator.setDaoGenerator(daoGenerator);
        serviceBaseGenerator.setModelGenerator(modelGenerator);
        serviceBaseGenerator.setServiceGenerator(serviceGenerator);

        // 执行生成
        if (enabledDao)
            daoGenerator.generator();
        if (enabledModelBase)
            modelBaseGenerator.generator();
        if (enabledModel)
            modelGenerator.generator();
        if (enabledService)
            serviceGenerator.generator();
        if (enabledServiceBase)
            serviceBaseGenerator.generator();
        if (enabledServiceImpl)
            serviceImplGenerator.generator();
    }
}
